package br.com.persist.core;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import br.com.persist.api.PersistentContext;
import br.com.persist.api.RuntimeExecutionException;
import br.com.persist.api.VolatileContext;

public class PackagePersistResource extends PersistResource {

	private static final String MAIN_FUNCTION = "main";
	private String packageName;
	private Set<Import> imports = new HashSet<Import>();
	private Map<String, FunctionPersistResource> functionsByName = new HashMap<String, FunctionPersistResource>();

	public PackagePersistResource(String packageName) {
		super();
		this.packageName = packageName;
	}

	public void addImport(String imp) {
		addImport(new Import(imp));
	}

	public void addImport(Import imp) {
		this.imports.add(imp);
	}

	public void addFunction(Function function) {
		FunctionPersistResource functionResource = new FunctionPersistResource(function);
		functionsByName.put(function.getName(), functionResource);
	}

	public FunctionPersistResource getFunctionWithName(String name) throws FunctionNotFoundException {
		if (!functionsByName.containsKey(name)) {
			throw new FunctionNotFoundException(packageName, name);
		}
		return functionsByName.get(name);
	}

	@Override
	protected Object run(VolatileContext volatileContext, PersistentContext persistentContext) throws RuntimeExecutionException {
		return getMainFunction().run(volatileContext, persistentContext);
	}

	protected PersistResource getMainFunction() throws FunctionNotFoundException {
		if (functionsByName.containsKey(MAIN_FUNCTION)) {
			return functionsByName.get(MAIN_FUNCTION);
		} else {
			throw new FunctionNotFoundException(packageName, "main");
		}
	}

	public String getPackageName() {
		return packageName;
	}

	public Set<Import> getImports() {
		return Collections.unmodifiableSet(imports);
	}
}
